home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
BBS_UTL
/
BOI200P
/
BOIDECL.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-12-13
|
13KB
|
371 lines
{ $D-} { Debug Information Off }
{$S-} { Stack Checking Off }
{$V-} { String Checking Off }
Unit BOIDecl;
{ Part of BBS Onliner Interface }
{ Copyright (C) 1990,1992 Andrew J. Mead
All Rights Reserved. }
{ original version 10/20/90
history found in IOLIB.PAS }
INTERFACE
Uses
crt,
DOS;
Const
BOI_Version = '1.40'; { BBS Onliner Interface Version Number }
{ DOS file sharing attributes, used with OpenFile, OpenText }
read_only = $00; { ---- -000 open file for read only }
writeonly = $01; { ---- -001 open file for write only }
readwrite = $02; { ---- -010 open file for reading and writing }
denyall = $10; { -001 ---- deny file access to other programs }
denywrite = $20; { -010 ---- deny write access to other programs }
denyread = $30; { -011 ---- deny read access to other programs }
denynone = $40; { -100 ---- allow full access to other programs }
Type
ptrmask = record { segment:offset mask for address pointers }
poff : word;
pseg : word
end;
timearr = array [1..4] of word; { used in Time/Date functions }
basearr = array [$0..$F] of byte;
facctype = (treset,trewrite,tappend); { file access modes }
tasktype = (notask,dv,dos5,win,os2); { CPU taskers }
boi_grmode = (gr_none,gr_ascii,gr_ansi,gr_avt,gr_tpcrt);
{ graphics modes : none, ASCII, ANSI, AVATAR, CRT }
boi_commode = (com_none,com_local,com_internal,com_fossil);
{ communication modes : none, local, internal, FOSSIL }
boi_statmodes = (sm_help1,sm_time,sm_comm,sm_vid);
{ status line display options : }
{ time left, comm settings, remote video mode }
boi_dropmode = (df_none,df_pcb14x,df_other);
{ drop file types : none, PCBoard 14.x, other }
stdproc = procedure; { procedural variable type }
Const
boi_r_color : boolean = false; { use color indicator (remote) }
boi_l_color : boolean = false; { use color indicator (local) }
boi_local : boolean = true; { local mode indicator }
boi_echo : boolean = false; { echo info locally indicator }
boi_quiet : boolean = false; { supress local bell ringing }
boi_ctsrts : boolean = false; { modem has locked baud rate }
boi_replay : boolean = false; { allow multiple play }
boi_checkcd : boolean = true; { use carrier detect routines }
boi_timeover : boolean = false; { time has expired indicator }
boi_againtime : word = 10; { time minimum for Again play }
boi_statmode : boi_statmodes = sm_time; { status line display mode }
boi_allowavt : boolean = false; { AVATAR allowed indicator }
dos_share : boolean = true; { DOS SHARE is loaded }
boi_portadd : word = $03F8; { Com1 } { serial port address }
boi_portnum : word = 0; { Com1 } { serial port number (absolute) }
boi_portint : word = $0C; { IRQ4 } { serial port interrupt vector }
boi_picmask : byte = $EF; { IRQ4 } { 8259A port initialization value }
boi_pic2msk : byte = $00; { if IRQ7..IRQ15 used then this is used }
boi_cascade : boolean = false; { IRQ7..IRQ15 used indicator }
boi_hoflim : byte = 20; { maximum entries by one player in HOF }
boi_plusidx : byte = 0; { GetCmBBS places ParamStr index value in }
boi_minusidx : byte = 0; { the given variable. These are the main }
boi_equalidx : byte = 0; { program definable variables. The program }
boi_closeidx : byte = 0; { must perform any further processing on }
boi_openidx : byte = 0; { these switches. }
boi_dotidx : byte = 0;
boi_portstatus : boolean = false; { internal Async not active }
boi_cmode : boi_commode = com_none; { remote communications mode }
boi_cstr : string = ' No Comm'; { status line comm mode string }
foss_init : byte = $00; { FOSSIL initialization option mask }
boi_dmode : boi_dropmode = df_none; { drop file mode }
boi_cdlost : boolean = false; { remote dropped carrier indicator }
boi_ticks : longint = $17fe80; { timer ticks left (18.2 per second) }
boi_stall : longint = 0; { timer ticks since last user activity}
boi_timer : longint = 0; { timer ticks into the game }
boi_stime : longint = 0; { time stat line was last updated }
boi_warntime : word = 5; { next minute to warn user about time at}
boi_ansiarr : basearr = { ANSI colors mapped to text attribute byte }
(30,34,32,36,31,35,33,37,30,34,32,36,31,35,33,37);
boi_l_grmode : boi_grmode = gr_tpcrt; { current local graphics mode }
boi_r_grmode : boi_grmode = gr_ansi; { current remote graphics mode }
boi_nextchar : char = #$00; { used to pass character to IOLib.GetString }
Type
str39 = string [39];
charset = set of char;
Var
boi_pagelength : byte; { size of screen in lines }
boi_username : str39; { player's name - if available }
boi_usename : boolean; { availability of users name }
boi_realname : str39; { player's real name (not alias) - if available }
boi_usereal : boolean; { availability of real name }
boi_gametime : integer; { playing time - if available }
boi_usetime : boolean; { use playing time indicator }
boi_ticksleft : longint; { time left to play }
boi_starttime : timearr; { time that game was initialized }
boi_startdate : timearr; { date that game was initialized }
boi_extraword : word; { reserved }
boi_timexp : boolean; { time expired indicator }
boi_texthof : pathstr; { text hall of fame filename }
boi_gamepath : pathstr; { full DOS path of game's executable }
boi_gamedir : dirstr; { DOS path of game }
boi_gamename : namestr; { DOS file name (no extension) of game }
boi_gameext : extstr; { DOS file name extension of current game }
boi_tasker : tasktype; { Operating System/Environment tasker }
boi_tvers : word; { version of boi_tasker }
boi_tstr : string; { string describing boi_tasker }
boi_tintr : boolean; { Interrupt for tasker functions }
in_dos : ^boolean; { DOS active indicator }
BOI_Wait : stdproc; { stall procedure / give up time slice }
BOI_Crit : stdproc; { enter critical region }
BOI_Safe : stdproc; { exit critical region }
Procedure BOIInt08h; Interrupt;
IMPLEMENTATION
{$F+}
Const
fossintr = $14; { FOSSIL interrupt }
dv_intr = $15; { DESQview interrupt }
dos_intr = $21; { DOS Services interrupt }
win_intr = $2F; { DOS Multiplexor/Windows interrupt }
lastwait : longint = 0; { static variable indicating last time slice }
{ that was surrendered }
Var
bd_nextexit : pointer; { pointer to hold address of next Exit procedure }
oldint08h : pointer; { pointer to hold previous Timer interrupt }
Procedure CALLOLDINT(old : pointer); Far;
begin {* CallOldInt *}
Inline($9C/$FF/$5E/$06)
end; {* CallOldInt *}
Procedure BOIINT08H;
{ chain timer interrupt to handle BOI timing routines }
begin {* iBOIInt08h *}
if boi_ticks = 0 then boi_timeover := true;
Dec(boi_ticks); { decrement time remaining }
Inc(boi_stall); { increment inactivity timer }
Inc(boi_timer); { increment game timer }
CallOldInt(oldint08h); { allow CPU to do its thing first }
Inline($FB) { STI } { allow other interrupts to intercede }
{ additional non-critical processing can go here, in the future
I plan to write a hook to this section... }
end; {* iBOIInt08h *}
Procedure NULLPROC; Far;
begin {* NullProc *}
end; {* NullProc *}
{ DESQview functions }
Procedure DV_WAIT; Far;
const
dvregs : registers = (ax : $1000);
begin {* DV_Wait *}
if boi_timer - lastwait >= 4 then { only give up one in four time slices }
begin
Intr(dv_intr,dvregs);
lastwait := boi_timer
end
end; {* DV_Wait *}
Procedure DV_CRIT; Far;
const
dvregs : registers = (ax : $DE1C);
begin {* DV_Crit *}
Intr(dv_intr,dvregs)
end; {* DV_Crit *}
Procedure DV_SAFE; Far;
const
dvregs : registers = (ax : $101C);
begin {* DV_Safe *}
Intr(dv_intr,dvregs)
end; {* DV_Safe *}
Function CHECKDV : boolean; { is DESQview loaded? }
var
regs : registers;
begin {* fCheckDV *}
regs.AX := $2B01;
regs.CX := $4445; { DE }
regs.DX := $5351; { SQ }
Intr($21,regs);
if regs.AL <> $FF then { set initial values }
begin
boi_tasker := dv;
boi_tvers := regs.BX;
boi_tintr := true;
BOI_Wait := DV_Wait;
BOI_Crit := DV_Crit;
BOI_Safe := DV_Safe;
Str(regs.BH + (regs.BL / 100):0:2,boi_tstr);
boi_tstr := 'DESQview ' + boi_tstr;
CheckDV := true
end
else CheckDV := false
end; {* fCheckDV *}
{ MicroSoft Windows functions }
Procedure MS_WAIT; Far;
const
msregs : registers = (ax : $1680);
begin {* MS_Wait *}
if boi_timer - lastwait >= 4 then { only give up one in four time slices }
begin
Intr(win_intr,msregs);
lastwait := boi_timer
end
end; {* MS_Wait *}
Procedure WIN_CRIT; Far;
const
winregs : registers = (ax : $1681);
begin {* Win_Crit *}
Intr(win_intr,winregs)
end; {* Win_Crit *}
Procedure WIN_SAFE; Far;
const
winregs : registers = (ax : $1682);
begin {* Win_Safe *}
Intr(win_intr,winregs)
end; {* Win_Safe *}
Function CHECKWINDOZE : boolean; { is MS Windows loaded? }
var
regs : registers;
begin {* fCheckWindoze *}
regs.AX := $1600;
Intr(win_intr,regs);
if regs.AL in [$00,$01,$80,$FF] then CheckWindoze := false
else
begin { set initial values }
boi_tasker := win;
boi_tvers := regs.AL;
boi_tintr := true;
BOI_Wait := MS_Wait;
BOI_Crit := Win_Crit;
BOI_Safe := Win_Safe;
Str(regs.AL + (regs.AH / 100):0:2,boi_tstr);
boi_tstr := 'Windows ' + boi_tstr;
CheckWindoze := true
end
end; {* fCheckWindoze *}
Procedure DOS_IDLE; Far;
begin {* DOS_Idle *}
Inline($CD/$28)
end; {* DOS_Idle *}
Procedure CHECKDOSVERS; { set up DOS/DOS box settings }
var
regs : registers;
begin {* CheckDOSVers *}
boi_tintr := false;
regs.AX := $3001; { test for DOS version }
Intr(dos_intr,regs);
if (regs.AL = $0A) or (regs.AL = $14) then { OS/2 1.x or OS/2 2.x }
begin { set OS/2 dos box settings }
boi_tasker := os2;
if regs.AL = $0A then
begin
boi_tvers := 1;
boi_tstr := 'OS/2 1.x'
end
else
begin
boi_tvers := 2;
boi_tstr := 'OS/2 2.x'
end;
BOI_Wait := MS_Wait; { works fine }
BOI_Crit := NullProc; {* Unknown *}
BOI_Safe := NullProc; {* Unknown *}
end
else
begin { set up DOS settings }
boi_tvers := regs.AX;
Str(regs.AL + (regs.AH / 100):0:2,boi_tstr);
boi_tstr := 'DOS ' + boi_tstr;
BOI_Crit := NullProc;
BOI_Safe := NullProc;
if regs.AL = 5 then { is DOS version 5.0? }
begin
boi_tasker := dos5;
BOI_Wait := MS_Wait
end
else
begin
boi_tasker := notask;
BOI_Wait := DOS_Idle
end
end
end; {* fCheckDOSVers *}
Procedure SETINDOS; { set up InDos flag }
type
ptrmap = array [0..1] of word;
var
regs : registers;
indos : ptrmap absolute in_dos;
begin {* SetInDOS *}
regs.AH := $34;
Intr(dos_intr,regs);
indos[1] := regs.ES;
indos[0] := regs.BX
end; {* SetInDOS *}
Procedure BOIEXIT; Far;
begin {* BOIExit *}
exitproc := bd_nextexit;
SetIntVec($08,oldint08h)
end; {* BOIExit *}
begin {* uBOIDecl *}
bd_nextexit := exitproc; { install BOIDecl's exit procedure }
exitproc := @BOIExit;
GetIntVec($08,oldint08h); { save current timer interrupt }
SetIntVec($08,@BOIInt08h); { insert BOI timer interrupt }
GetDate(boi_startdate[1],boi_startdate[2],boi_startdate[3],boi_startdate[4]);
{ set starting date }
GetTime(boi_starttime[1],boi_starttime[2],boi_starttime[3],boi_starttime[4]);
{ set starting time }
boi_gamepath := FExpand(ParamStr(0)); { find out who we are! }
FSplit(boi_gamepath,boi_gamedir,boi_gamename,boi_gameext); { split file }
SetInDOS; { get indos flag }
{ set up CPU tasker stuff }
if not CheckDV then if not CheckWindoze then CheckDOSVers
end. {* uBOIDecl *}